---
title: MyBatis select 
---
select 标签用于映射 SQL 中的查询语句。

## xml 方式
将 select 查询写在 mapper.xml 文件中，例如：
```xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="pub.wkq.mybatis.mapper.UserMapper">

    <select id="selectUsernameById" resultType="java.lang.String">
        select username from imooc_user where id = #{id}
    </select>
</mapper>
```
`<select>` 标签的属性说明如下：
1. selectUserAgeById：方法名，与接口中的方法名一致。
2. resultType：返回值类型，与接口中的方法返回值类型一致。
3. #{id}：方法参数，与接口中的方法参数一致。
4. select username from imooc_user where id = #{id}：SQL 语句。
5. select：SQL 语句类型，select 表示查询语句。
6. username：查询结果的列名，与 resultType 一致。
7. imooc_user：查询的表名。
8. where id = #{id}：查询条件，与方法参数一致。
9. id：查询条件的列名，与方法参数一致。

`#{}` 作为参数符号， MyBatis 则会创建一个预处理语句（PreparedStatement），它会被处理成 ? 。如果不希望使用预处理，那么可以使用 `${}` 作为参数符号， MyBatis 则会将其以字符串的形式进行拼接，这样就会有 SQL 注入的风险。
## 注解方式
在接口中使用注解的方式，例如：
```java
package pub.wkq.mybatis.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

/**
 * UserMapper.java
 */
@Mapper
public interface UserMapper {
    /**
     * 根据用户id查询用户信息
     *
     * @param id 用户id
     * @return 用户信息
     */
    @Select("SELECT username FROM imooc_user WHERE id = #{id}")
    String selectUsernameById(@Param("id") Integer id);
}

```
## select 属性
select 标签支持很多属性来改变查询语句的行为。以下是一些重要的属性：

| 属性          | 描述                                                         |
| ------------- | ------------------------------------------------------------ |
| id            | 在命名空间中唯一的标识符。                                   |
| parameterType | 语句的参数类型，默认可选，MyBatis 会自动推断。               |
| resultType    | 语句返回值类型，如果返回的是集合，那应该设置为集合包含的类型。 |
| resultMap     | 语句返回映射的 id，可以使用 resultMap 和 resultType，但不能同时使用。 |
| flushCache    | 设置为 true 后，只要语句被调用，都会导致本地缓存和二级缓存被清空，默认为 false。 |
| useCache      | 设置为 true 后，本条语句的查询结果被二级缓存缓存起来，默认 select 标签为 true。 |
| timeout       | 设置超时时间                                                 |
| fetchSize     | 设置预期返回的记录数量                                       |
| statementType | STATEMENT、PREPARED 和 CALLABLE 中的一个，默认为 PREPARED(预处理) |

## 参数

### 对象参数

```xml
<select id="selectUserByAgeAndScore" parameter="pub.wkq.mybatis.entity.User" resultType="pub.wkq.mybatis.entity.User">
    select * from imooc_user where age = #{age} and score = #{score}
</select>
```
selectUserByAgeAndScore 方法的参数为 User 对象，其中 age 和 score 为 User 对象的属性，#{age} 和 #{score} 会分别替换成 User 对象的 age 和 score 属性。

### Map 参数

```xml
<select id="selectUserByAgeAndScore" parameterType="map" resultType="pub.wkq.mybatis.entity.User">
    select * from imooc_user where age = #{age} and score = #{score}
</select>
```
selectUserByAgeAndScore 方法的参数为 Map 对象，其中 age 和 score 为 Map 对象的 key，#{age} 和 #{score} 会分别替换成 Map 对象的 age 和 score 属性。

### 参数配置
`#{}` 不仅可以传入参数名称，还可以传入参数类型和类型处理器。
    
```txt
#{age, javaType=int, jdbcType=int, typeHandler=org.apache.ibatis.type.IntegerTypeHandler}
```
1. javaType: 表示 age 的 Java 类型。
2. jdbcType: 表示 age 的 JDBC 类型。
3. typeHandler: 表示 age 的类型处理器。

对于参数配置，90% 的情况下都不需要配置， MyBatis 会自动推断出参数类型和类型处理器。


